package qlsl.androiddesign.api.util.commonutil;

import android.app.Activity;
import android.view.View;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;

import qlsl.androiddesign.api.activity.R;

/**
 * 类描述：反射工具类
 * 需要传入的键：****
 * 传入的值类型：****
 * 传入的值含义：****
 * 是否必传：****
 * 作者：郑朝军 on 2017/6/14 11:29
 * 邮箱：1250393285@qq.com
 * 公司：武汉智博创享科技有限公司
 * 修改人：郑朝军 on 2017/6/14 11:29
 * 修改备注：
 */
public class ReflectUtil
{
    /**
     * 动态创建实例对象 耗性能 尽量少调用
     *
     * @param o
     * @param i
     * @param <T>
     * @return
     */
    public static <T> T getT(Object o, int i)
    {
        try
        {
            return ((Class<T>) ((ParameterizedType) (o.getClass()
                    .getGenericSuperclass())).getActualTypeArguments()[i])
                    .newInstance();
        }
        catch (InstantiationException e)
        {
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        catch (ClassCastException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 动态获取泛型的对应位置的位置的Class
     *
     * @param o
     * @param i
     * @return
     */
    public static Class getClazz(Object o, int i)
    {
        try
        {
            return ((Class) ((ParameterizedType) (o.getClass()
                    .getGenericSuperclass())).getActualTypeArguments()[i]);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据一个对象的私有属性获取该私有属性的值，不支持父类查找
     *
     * @param o      该对象
     * @param column 该对象的列名
     * @return 返回该对象列名的值
     * @throws Exception
     */
    public static Object getPrivateValue(Object o, String column) throws Exception
    {
        Field field = o.getClass().getDeclaredField(column);
        Object object = field.get(o);
        return object;
    }

    public static Class<?> forName(String className)
    {
        try
        {
            return Class.forName(className);
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * activity自动findview
     */
    public static void autoFind(Activity activity)
    {
        try
        {
            Class<?> clazz = activity.getClass();
            Field[] fields = clazz.getDeclaredFields();// 获得Activity中声明的字段
            for (Field field : fields)
            {
                if (field.getGenericType().toString().contains("widget")
                        || field.getGenericType().toString().contains("view")
                        || field.getGenericType().toString()
                        .contains("WebView"))
                {// 找到所有的view和widget,WebView
                    try
                    {
                        String name = field.getName();
                        Field idfield = R.id.class.getField(name);
                        int id = idfield.getInt(new R.id());// 获得view的id
                        field.setAccessible(true);
                        field.set(activity, activity.findViewById(id));// 给我们要找的字段设置值
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (NoSuchFieldException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * Fragment以及ViewHolder等自动findview
     */

    public static void autoFind(Object obj, View view)
    {
        try
        {
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();// 获得Activity中声明的字段
            for (Field field : fields)
            {
                if (field.getGenericType().toString().contains("widget")
                        || field.getGenericType().toString().contains("view")
                        || field.getGenericType().toString()
                        .contains("WebView"))
                {// 找到所有的view和widget
                    try
                    {
                        String name = field.getName();
                        Field idfield = R.id.class.getField(name);
                        int id = idfield.getInt(new R.id());
                        field.setAccessible(true);
                        field.set(obj, view.findViewById(id));// 给我们要找的字段设置值
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }
                    catch (NoSuchFieldException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 获取obj对象fieldName的Field
     *
     * @param obj
     * @param fieldName
     * @return
     */
    public static Field getFieldByFieldName(Object obj, String fieldName)
    {
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass
                .getSuperclass())
        {
            try
            {
                return superClass.getDeclaredField(fieldName);
            }
            catch (NoSuchFieldException e)
            {
                return null;
            }
        }
        return null;
    }

    /**
     * 获取obj对象fieldName的属性值
     *
     * @param obj
     * @param fieldName
     * @return
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static Object getValueByFieldName(Object obj, String fieldName)
            throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException
    {
        Field field = getFieldByFieldName(obj, fieldName);
        Object value = null;
        if (field != null)
        {
            if (field.isAccessible())
            {
                value = field.get(obj);
            }
            else
            {
                field.setAccessible(true);
                value = field.get(obj);
                field.setAccessible(false);
            }
        }
        return value;
    }

    /**
     * 设置obj对象fieldName的属性值
     *
     * @param obj
     * @param fieldName
     * @param value
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void setValueByFieldName(Object obj, String fieldName,
                                           Object value) throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException
    {
        Field field = obj.getClass().getDeclaredField(fieldName);
        if (field.isAccessible())
        {
            field.set(obj, value);
        }
        else
        {
            field.setAccessible(true);
            field.set(obj, value);
            field.setAccessible(false);
        }
    }

    /**
     * 获取某文件中的ID
     *
     * @param className
     * @param name
     * @return
     */
    public static int getResourceID(Class className, String name)
    {
        try
        {
            Field field = className.getField(name);
            int resId = field.getInt(name);
            return resId;
        }
        catch (NoSuchFieldException e)
        {
            return 0;
        }
        catch (IllegalAccessException e)
        {
            return 0;
        }
    }


    /**
     * 获取布局文件中的ID
     *
     * @param name
     * @return
     */
    public static int getLayoutResourceID(String name)
    {
        Class layout = R.layout.class;
        try
        {
            Field field = layout.getField(name);
            int resId = field.getInt(name);
            return resId;
        }
        catch (NoSuchFieldException e)
        {
            return 0;
        }
        catch (IllegalAccessException e)
        {
            return 0;
        }
    }

    /**
     * 动态的根据一个字符串资源名获得到对应的资源id:如根据不同的图片名称获得对应的图片,此时就应该考虑如何实现.
     *
     * @param imageName
     * @return 0 未获取ID
     */
    public static int getImageResourceID(String imageName)
    {
        Class mipmap = R.mipmap.class;
        try
        {
            Field field = mipmap.getField(imageName);
            int resId = field.getInt(imageName);
            return resId;
        }
        catch (NoSuchFieldException e)
        {
            return getDrawableResource(imageName);
        }
        catch (IllegalAccessException e)
        {
            return 0;
        }
    }

    /**
     * 动态的根据一个字符串资源名获得到对应的资源id:如根据不同的图片名称获得对应的图片,此时就应该考虑如何实现.
     *
     * @param imageName Drawable文件中
     * @return 0 未获取ID
     */
    public static int getDrawableResource(String imageName)
    {
        Class mipmap = R.drawable.class;
        try
        {
            Field field = mipmap.getField(imageName);
            int resId = field.getInt(imageName);
            return resId;
        }
        catch (NoSuchFieldException e)
        {
            return 0;
        }
        catch (IllegalAccessException e)
        {
            return 0;
        }
    }
}
